/**
	Copyright (c) 2010 ATTi 
	All rights reserved.
	Author: Michael Shu
	Date: 1/22/2010
*/
/**
    Test Class. contains test methods for Account and Opportunity Sharing Trigger Test
    Test Class for AccountCMRTrigger
*/

@isTest

private class AccOppSharingTriggerTester {
	private static Integer i, NUM_ROWS = 10;
	private static Account acc;
	private static Opportunity opp;
	private static List<Account> lAcc;
	private static List<Opportunity> lOpp;
	private static List<AccountShare> lAccshr;
	private static List<OpportunityShare> lOppshr;
	private static List<User> lUser; // user list, used for account manager
	private static Map<ID, Account> mAcc;
	private static Map<ID, Opportunity> mOpp;
	private static Map<ID, String> mUser; // map of user Name by ID
	private static ID AdvancedAdSolutions_RecordTypeId_Acc;
	private static ID AdvancedAdSolutions_RecordTypeId_Opp;
	private static User sysAdmins;
	
	static testmethod void testAccSharingTrigger(){
		init(); // initialize
		for(i = 0; i < NUM_ROWS; i++){
			acc = new Account();
			acc.Name = 'TestAccSharing_' + i;
			acc.RecordTypeId = AdvancedAdSolutions_RecordTypeId_Acc;
			acc.Account_Manager__c = lUser[i].Name; // from 0 to NUM_ROWS - 1
			lAcc.add(acc);
		}
		System.runAs(sysAdmins){
			insert lAcc;  // insert account
		}
		mAcc = new Map<ID, Account>([select a.Id, a.Name, a.Account_Manager__c from Account a where a.Name like '%TestAccSharing_%']);
		System.assertEquals(NUM_ROWS, mAcc.size()); // check the record number
		lAccshr = [select a.Id, a.AccountId, a.AccountAccessLevel, a.CaseAccessLevel, a.OpportunityAccessLevel, a.UserOrGroupId 
		           from AccountShare a where a.AccountID In: mAcc.keySet() and a.RowCause = 'Manual'];
		for(AccountShare a : lAccshr){
			// compare the Account Manager Name between account and account share
			System.debug('--test1-- Account Manager = ' + mAcc.get(a.AccountId).Account_Manager__c + '; a.UserOrGroupId = ' + a.UserOrGroupId); 
			System.assertEquals(mAcc.get(a.AccountId).Account_Manager__c,  mUser.get(a.UserOrGroupId));
		} 
		
		i = 0;
		// update Account Manager in Account
		for(Account a : mAcc.values()){
			a.Account_Manager__c = lUser[i+NUM_ROWS].Name; // from  NUM_ROWS to NUM_ROWS*2-1
			i = i + 1;
		}
		System.runAs(sysAdmins){
			update mAcc.values();
		}
		mAcc = new Map<ID, Account>([select a.Id, a.Name, a.Account_Manager__c from Account a where a.Name like '%TestAccSharing_%']);
		System.assertEquals(NUM_ROWS, mAcc.size()); // check the record number
		lAccshr = [select a.Id, a.AccountId, a.AccountAccessLevel, a.CaseAccessLevel, a.OpportunityAccessLevel, a.UserOrGroupId 
		           from AccountShare a where a.AccountID In: mAcc.keySet() and a.RowCause = 'Manual'];
		for(AccountShare a : lAccshr){
			// compare the Account Manager Name between account and account share 
			System.assertEquals(mAcc.get(a.AccountId).Account_Manager__c,  mUser.get(a.UserOrGroupId));
		}		
	}
	
	static testmethod void testOppSharingTrigger(){
		init(); // initialize
		acc = new Account();
		acc.Name = 'TestAccSharing_';
		acc.RecordTypeId = AdvancedAdSolutions_RecordTypeId_Acc;
		acc.Account_Manager__c = lUser[0].Name; //
		Database.Saveresult sr_acct;
		System.runAs(sysAdmins){
			sr_acct = Database.insert(acc);  // insert account
		}
		for(i = 0; i < NUM_ROWS; i++){
			opp = new Opportunity();
			opp.Name = 'TestOppSharing_' + i;
			opp.RecordTypeId = AdvancedAdSolutions_RecordTypeId_Opp;
			opp.Account_Manager__c = lUser[i].Name; // from 0 to NUM_ROWS - 1
			opp.StageName = 'Prospecting';
			opp.AccountId = sr_acct.getId();
			opp.CloseDate = Date.today();
			lOpp.add(opp);
		}
		System.runAs(sysAdmins){
			insert lOpp;  // insert Opportunity
		}
		mOpp = new Map<ID, Opportunity>([select a.Id, a.Name, a.Account_Manager__c from Opportunity a where a.Name like '%TestOppSharing_%']);
		System.assertEquals(NUM_ROWS, mOpp.size()); // check the record number
		lOppshr = [select o.Id, o.OpportunityId, o.OpportunityAccessLevel, o.UserOrGroupId 
		           from OpportunityShare o where o.OpportunityID In: mOpp.keySet() and o.RowCause = 'Manual'];
		for(OpportunityShare o : lOppshr){
			// compare the Opportunity Manager Name between Opportunity and Opportunity share 
			System.debug('--test2-- Account Manager = ' + mOpp.get(o.OpportunityId).Account_Manager__c + '; o.UserOrGroupId = ' + o.UserOrGroupId); 
			System.assertEquals(mOpp.get(o.OpportunityId).Account_Manager__c,  mUser.get(o.UserOrGroupId));
		} 
		
		i = 0;
		// update Account Manager in Opportunity
		for(Opportunity a : mOpp.values()){
			a.Account_Manager__c = lUser[i+NUM_ROWS].Name; // from  NUM_ROWS to NUM_ROWS*2-1
			i = i + 1;
		}
		System.runAs(sysAdmins){
			update mOpp.values();
		}
		mOpp = new Map<ID, Opportunity>([select a.Id, a.Name, a.Account_Manager__c from Opportunity a where a.Name like '%TestOppSharing_%']);
		System.assertEquals(NUM_ROWS, mopp.size()); // check the record number
		lOppshr = [select o.Id, o.OpportunityId, o.OpportunityAccessLevel, o.UserOrGroupId 
		           from OpportunityShare o where o.OpportunityID In: mOpp.keySet() and o.RowCause = 'Manual'];
		for(OpportunityShare o : lOppshr){
			// compare the Opportunity Manager Name between Opportunity and Opportunity share 
			System.assertEquals(mOpp.get(o.OpportunityId).Account_Manager__c,  mUser.get(o.UserOrGroupId));
		}		
	}
		
	private static void init(){
		lAcc = new List<Account>();
		lOpp = new List<Opportunity>();
		lAccshr = new List<AccountShare>();
		lOppshr = new List<OpportunityShare>();
		mAcc = new Map<ID, Account>();
		mOpp = new Map<ID, Opportunity>();
		mUser = new Map<ID, String>();
		lUser = new List<User>([select u.Name, u.Id from User u where IsActive = true Order By u.Name limit 100]);
		for(User u : lUser){
			System.debug('--test0-- user Id = ' + u.ID + ' and user Name = ' + u.Name); 
			mUser.put(u.ID, u.Name);
		}
		User u_new = new User();
		u_new.UserName = 'xyz_1234567890@atti-temp.com';
		u_new.LastName = 'Michael Shu Admin Test';
		u_new.Email = 'admin-null@atti.com';
		u_new.Alias = 'admin_me';
		u_new.CommunityNickname = 'admin123456' + i;
		u_new.TimeZoneSidKey = 'America/Los_Angeles';
		u_new.LocaleSidKey = 'en_US';
		u_new.EmailEncodingKey = 'UTF-8';
		u_new.ProfileId = [select ID from Profile where Name =: 'System Administrator' limit 1].Id;
		u_new.UserRoleId = [select ID from UserRole where Name =: 'Information Systems' limit 1].Id;
		u_new.LanguageLocaleKey = 'en_US';
		Database.Saveresult u_sr = Database.insert(u_new);	
		sysAdmins = [select ID from User where ID =: u_sr.getID() limit 1];
		
		RecordTypeHelper.PrepareToLoad('Account');		
		RecordTypeHelper.PrepareToLoad('Opportunity');		
		AdvancedAdSolutions_RecordTypeId_Acc = RecordTypeHelper.GetRecordTypeID('Account', 'AAS Sales Account');		
		AdvancedAdSolutions_RecordTypeId_Opp =RecordTypeHelper.GetRecordTypeID('Opportunity', 'Advanced Ad Solutions');
	} 
	
	static testmethod void testAccountCMRTrigger(){
		lAcc = new List<Account>();
		for(i = 0; i < 1; i++){
			acc = new Account();
			acc.Name = 'TestAccountCMRTrigger_Agency' + i;
			acc.RecordTypeId = [select Id from RecordType where Name = 'CMR Agency' limit 1].Id;
			acc.CMR_ID__c = '9523';
			lAcc.add(acc);
		}
		insert lAcc;
		List<Account> acc_rsts = [select id, CMR_ID__c from Account where Name like 'TestAccountCMRTrigger_Agency%'];
		lAcc = new List<Account>();
		for(i = 0; i < NUM_ROWS; i++){
			acc = new Account();
			acc.Name = 'TestAccountCMRTrigger_CMR' + i;
			acc.RecordTypeId = [select Id from RecordType where Name = 'CMR Agency' limit 1].Id;
			acc.Agency__c = acc_rsts[0].Id;
			acc.Account_Status__c = 'Draft';
			acc.CMR_ID__c = '73' + i;
			lAcc.add(acc);
		}
		//insert lAcc;
		
		acc_rsts[0].CMR_ID__c = '234';
		//update acc_rsts;
		
		List<Account> acc_CMR_rsts = [select id, CMR_Client_Code_Text__c from Account where Name like 'TestAccountCMRTrigger_CMR%'];
		for(Account a : acc_CMR_rsts){
			//System.assertEquals(a.CMR_Client_Code__c, a.CMR_Client_Code_Text__c);
		}
	}
}